import numpy as np

# Expected values for matrices in subdivide_bezier and others
# Note that in bezier.py this is a list of dicts,
# not a dict of dicts!
SUBDIVISION_MATRICES = {
    # For 0-degree Béziers
    0: {
        2: np.array([[1], [1]]),
        3: np.array([[1], [1], [1]]),
        4: np.array([[1], [1], [1], [1]]),
    },
    # For linear Béziers
    1: {
        2: np.array(
            [
                [2, 0],
                [1, 1],
                [1, 1],
                [0, 2],
            ]
        )
        / 2,
        3: np.array(
            [
                [3, 0],
                [2, 1],
                [2, 1],
                [1, 2],
                [1, 2],
                [0, 3],
            ]
        )
        / 3,
        4: np.array(
            [
                [4, 0],
                [3, 1],
                [3, 1],
                [2, 2],
                [2, 2],
                [1, 3],
                [1, 3],
                [0, 4],
            ]
        )
        / 4,
    },
    # For quadratic Béziers
    2: {
        2: np.array(
            [
                [4, 0, 0],
                [2, 2, 0],
                [1, 2, 1],
                [1, 2, 1],
                [0, 2, 2],
                [0, 0, 4],
            ]
        )
        / 4,
        3: np.array(
            [
                [9, 0, 0],
                [6, 3, 0],
                [4, 4, 1],
                [4, 4, 1],
                [2, 5, 2],
                [1, 4, 4],
                [1, 4, 4],
                [0, 3, 6],
                [0, 0, 9],
            ]
        )
        / 9,
        4: np.array(
            [
                [16, 0, 0],
                [12, 4, 0],
                [9, 6, 1],
                [9, 6, 1],
                [6, 8, 2],
                [4, 8, 4],
                [4, 8, 4],
                [2, 8, 6],
                [1, 6, 9],
                [1, 6, 9],
                [0, 4, 12],
                [0, 0, 16],
            ]
        )
        / 16,
    },
    # For cubic Béziers
    3: {
        2: np.array(
            [
                [8, 0, 0, 0],
                [4, 4, 0, 0],
                [2, 4, 2, 0],
                [1, 3, 3, 1],
                [1, 3, 3, 1],
                [0, 2, 4, 2],
                [0, 0, 4, 4],
                [0, 0, 0, 8],
            ]
        )
        / 8,
        3: np.array(
            [
                [27, 0, 0, 0],
                [18, 9, 0, 0],
                [12, 12, 3, 0],
                [8, 12, 6, 1],
                [8, 12, 6, 1],
                [4, 12, 9, 2],
                [2, 9, 12, 4],
                [1, 6, 12, 8],
                [1, 6, 12, 8],
                [0, 3, 12, 12],
                [0, 0, 9, 18],
                [0, 0, 0, 27],
            ]
        )
        / 27,
        4: np.array(
            [
                [64, 0, 0, 0],
                [48, 16, 0, 0],
                [36, 24, 4, 0],
                [27, 27, 9, 1],
                [27, 27, 9, 1],
                [18, 30, 14, 2],
                [12, 28, 20, 4],
                [8, 24, 24, 8],
                [8, 24, 24, 8],
                [4, 20, 28, 12],
                [2, 14, 30, 18],
                [1, 9, 27, 27],
                [1, 9, 27, 27],
                [0, 4, 24, 36],
                [0, 0, 16, 48],
                [0, 0, 0, 64],
            ]
        )
        / 64,
    },
    # Test case with a quartic Bézier
    # to check if the fallback algorithms work
    4: {
        2: np.array(
            [
                [16, 0, 0, 0, 0],
                [8, 8, 0, 0, 0],
                [4, 8, 4, 0, 0],
                [2, 6, 6, 2, 0],
                [1, 4, 6, 4, 1],
                [1, 4, 6, 4, 1],
                [0, 2, 6, 6, 2],
                [0, 0, 4, 8, 4],
                [0, 0, 0, 8, 8],
                [0, 0, 0, 0, 16],
            ]
        )
        / 16,
    },
}
